import { cloneDeep } from 'g6-fn'
import { computed, onBeforeUnmount, ref } from 'vue'
import { useRequest } from 'vue-request'

import { useLoadingStore } from '@/store/loading'

export interface ResponseData {
  code: string
  message: string
  data: {
    records: any[]
    total: number
  }
}

interface PageInfo {
  offset: number
  limit: 10 | 20 | 50 | 100
  total: number
}

interface Options {
  isShowLoading?: boolean // 是否显示loading
  isPullDownLoading?: boolean // 是否下拉加载
  isOpenSync?: boolean // 是否启用轮询同步列表数据
  afterCallback?: (dataList: any[]) => void // 获取数据后的回调
}

const defaultOptions: Options = {
  isShowLoading: true,
  isPullDownLoading: false,
  isOpenSync: false
}

const { openLoading, closeLoading } = useLoadingStore()

export default function <Params, D>(api: any, otherParams: Params, options: Partial<Options> = {}) {
  // 获取数据
  const { data, runAsync: runGetDateList, loading } = useRequest<ResponseData>(api, { throttleInterval: 0 })
  // 初始化配置
  const { isShowLoading, isPullDownLoading, afterCallback, isOpenSync } = { ...defaultOptions, ...options }
  // 初始化查询数据
  type PageForm = PageInfo & Params
  const pageForm = ref<PageForm>({ offset: 1, limit: 10, total: 0, ...otherParams })
  const initPageForm = cloneDeep(pageForm.value) //复制一份
  const dataList = ref<D[]>([])
  const hasNextPage /* 是否还有下一页 */ = computed(() => pageForm.value.offset * pageForm.value.limit < pageForm.value.total)
  // 同步状态的轮询计时器
  let syncStateTimer: any = null

  // const previousPageForm = ref<PageForm>(cloneDeep(Object.assign(pageForm.value, otherParams))) //上一个pageForm
  const previousPageForm = ref<PageForm>(cloneDeep(pageForm.value)) //上一个
  // 获取数据
  const getDataList = async (otherParams?: Partial<PageForm>) => {
    if (isOpenSync) {
      syncState()
    }

    isShowLoading && openLoading()
    await runGetDateList(Object.assign(pageForm.value, otherParams))
    previousPageForm.value = cloneDeep(Object.assign(pageForm.value, otherParams))
    isShowLoading && closeLoading()
    const resDataList = data.value?.data.records || []
    const total = data.value?.data.total || 0

    // 下拉加载处理
    if (isPullDownLoading) {
      dataList.value.push(...resDataList)
      pageForm.value.total = total
      afterCallback && afterCallback(dataList.value)
      return
    }

    dataList.value = resDataList
    // 当前页码数大于最大页码数时，重置页码数
    const maxOffset = Math.ceil(total / pageForm.value.limit)

    if (maxOffset && pageForm.value.offset > maxOffset) {
      // console.log('重置页码数')

      getDataList({ offset: maxOffset } as Partial<PageForm>)
      return
    }
    pageForm.value.total = total
    afterCallback && afterCallback(dataList.value)
  }

  const resetPageForm = (resetData?: Partial<PageForm>) => {
    dataList.value = []
    Object.assign(pageForm.value, initPageForm, resetData)
    getDataList()
  }

  /**
   * 同步表格数据状态
   */
  const syncState = async () => {
    syncStateTimer && clearInterval(syncStateTimer)

    syncStateTimer = setTimeout(async () => {
      try {
        const res = await api(pageForm.value)
        const newDataList = res.data.records
        dataList.value.forEach((it, index) => {
          const newData = newDataList.find((newIt: D) => newIt.id === it.id)
          if (newData) {
            dataList.value[index] = { ...newData }
          }
        })
      } catch (error) {}

      syncState()
    }, 3000)
  }

  // 销毁
  const destroy = () => {
    syncStateTimer && clearTimeout(syncStateTimer)
  }

  onBeforeUnmount(() => {
    destroy()
  })

  return {
    destroy,
    pageForm,
    dataList,
    loading,
    hasNextPage,
    getDataList,
    resetPageForm,
    previousPageForm
  }
}
